#ifndef __M_SERVER_H__
#define __M_SERVER_H__
#include<iostream>
#include<vector>
#include<string>
#include<cassert>
#include<ctime>
#include<cstring>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/epoll.h>
#include<functional>
#include<unordered_map>
#include<memory>
#include<thread>
#include<mutex>
#include <sys/timerfd.h>
#include<typeinfo>
#include<condition_variable>
#include<sys/eventfd.h>
#include<sys/signal.h>
#define INF 0
#define DBG 1
#define ERR 2

#define LOG_LEVEL INF

#define LOG(level,format,...)do{\
    if(level<LOG_LEVEL) break;\
    time_t t = time(NULL);\
    struct tm *ltm = localtime(&t);\
    char tmp[32]={0};\
    strftime(tmp,31,"%H:%M:%S",ltm);\
    fprintf(stdout,"[%p %s %s:%d]" format "\n",(void*)pthread_self(),tmp,__FILE__,__LINE__,##__VA_ARGS__);\
}while(0)

#define INF_LOG(format,...) LOG(INF,format,##__VA_ARGS__)
#define DBG_LOG(format,...) LOG(DBG,format,##__VA_ARGS__)
#define ERR_LOG(format,...) LOG(ERR,format,##__VA_ARGS__)

class Any
{
private:
    class holder
    {
    public:
        virtual ~holder(){}
        virtual const std::type_info& type() = 0;//纯虚函数
        virtual holder *clone() = 0;
    };
    
    template<class T>
    class placeholder:public holder
    {
    public:
        T _val;
    public:
        placeholder(const T& val)
            :_val(val)
        {}
        virtual const std::type_info& type(){return typeid(T);}
        virtual holder *clone(){return new placeholder(_val);}
    };
    holder *_content;
public:
    Any()
        :_content(NULL)
    {}
    template<class T>
    Any(const T& val)
        :_content(new placeholder<T>(val))
    {}
    Any(const Any &other)
        :_content(other._content?other._content->clone():NULL)
    {}
    Any &swap(Any &other)
    {
        std::swap(_content,other._content);
        return *this;
    }
    ~Any(){delete _content;}
    //赋值重载
    template<class T>
    Any& operator=(const T& val)
    {
        Any(val).swap(*this);
        return *this;
    }
    Any& operator=(const Any &other)
    {
        Any(other).swap(*this);
        return *this;
    }
    //返回子类对象保存的数据的指针
    template<class T>
    T *get()
    {
        assert(typeid(T)==_content->type());
        return &((placeholder<T>*)_content)->_val;
    }
};
#define BUFFER_DEFAULT_SIZE 1024
class Buffer
{
private:
    std::vector<char> _buffer;
    uint64_t _reader_idx;//读偏移
    uint64_t _writer_idx;//写偏移
public:
    Buffer()
        :_reader_idx(0)
        ,_writer_idx(0)
        ,_buffer(BUFFER_DEFAULT_SIZE)
    {}
    char* Begin(){return &*_buffer.begin();}
    //获取当前写入的起始地址---_buffer的空间的起始地址+写偏移
    char* WritePosition(){return Begin()+_writer_idx;}
    //获取当前读取的起始地址---_buffer的空间的起始地址+读偏移
    char* ReadPosition(){return Begin()+_reader_idx;}
    //获取缓冲区末尾空闲空间----缓冲区的大小减去写偏移量
    uint64_t TailIdleSize(){return _buffer.size()-_writer_idx;}
    //获取缓冲区起始空闲空间----读偏移量
    uint64_t HeadIdleSize(){return _reader_idx;}
    //获取可读数据的大小----写偏移量减去读偏移量
    uint64_t ReadAbleSize(){return _writer_idx-_reader_idx;}
    //将读偏移往后移动
    void MoveReadOffset(uint64_t len)
    {
        if(len==0) return;
        assert(len<=ReadAbleSize());
        _reader_idx+=len;
    }
    //将写偏移往后移动
    void MoveWriteOffset(uint64_t len)
    {
        assert(len<=TailIdleSize());
        _writer_idx+=len;
    }
    //确保可写空间足够
    void EnsureWriteSpace(uint64_t len)
    {
        //1.末尾可写空间足够
        if(len<=TailIdleSize()) {return;}
        //2.末尾空间加上前面的空间才足够
        if(len<=TailIdleSize()+HeadIdleSize())
        {
            //将数据移动到起始位置，就是将数据往前挪
            //先保存可读数据的大小
            uint64_t rsz = ReadAbleSize();
            //移动--也就是拷贝
            std::copy(ReadPosition(),ReadPosition()+rsz,Begin());
            //此时空闲的位置连续了
            //将写偏移和读偏移修改一下
            _reader_idx = 0;
            _writer_idx = rsz;
        }
        else//3.加起来都不够，需要扩容
        {
            //总体空间不够，则需要扩容，不移动数据，直接给写偏移之后扩容足够空间即可
            DBG_LOG("RESIZE %ld", _writer_idx + len);
            _buffer.resize(_writer_idx+len);
        }
    }
    //写入数据
    void Write(const void* data,uint64_t len)
    {
        //保证有足够的空间去写入数据
        if(len==0) return;
        EnsureWriteSpace(len);
        //将数据的类型转化成char*类型
        const char* d= (const char*)data;
        //拷贝到buffer中
        std::copy(d,d+len,WritePosition());
    }
    //写入数据的同时，让写偏移往后走
    void WriteAndPush(const void* data,uint64_t len)
    {
        Write(data,len);
        MoveWriteOffset(len);
    }
    //写入的数据是string类型的
    void WriteString(const std::string& data)
    {
        return Write(data.c_str(),data.size());
    }
    //写入string类型的数据的同时，写偏移向后走
    void WriteStringAndPush(const std::string& data)
    {
        WriteString(data);
        MoveWriteOffset(data.size());
    }
    //写入的是Buffer对象中的数据
    void WriteBuffer(Buffer& data)
    {
        return Write(data.ReadPosition(),data.ReadAbleSize());
    }
    //写入Buffer对象的数据的同时，写偏移往后走
    void WriteBufferAndPush(Buffer& data)
    {
        WriteBuffer(data);
        MoveWriteOffset(data.ReadAbleSize());
    }
    //读取数据
    void Read(void *buf,uint64_t len)
    {
        assert(len<=ReadAbleSize());
        std::copy(ReadPosition(),ReadPosition()+len,(char*)buf);
    }
    //读取数据的同时，读偏移向后走
    void ReadAndPop(void *buf,uint64_t len)
    {
        Read(buf,len);
        MoveReadOffset(len);
    }
    //读取string类型的数据
    std::string ReadAsString(uint64_t len)
    {
        assert(len<=ReadAbleSize());
        std::string str;//用于存放数据
        str.resize(len);//开辟空间来存放数据
        Read(&str[0],len);
        return str;
    }
    //读取string类型的数据的同时，读偏移往后走
    std::string ReadAsStringAndPop(uint64_t len)
    {
        assert(len<=ReadAbleSize());
        std::string str = ReadAsString(len);
        MoveReadOffset(len);
        return str;
    }
    //获取换行字符的位置
    char* FindCRLF()
    {
        char *res = (char*)memchr(ReadPosition(),'\n',ReadAbleSize());
        return res;
    }
    //获取一行数据
    std::string GetLine()
    {
        char *pos = FindCRLF();//获取\n的位置
        if(pos==NULL) return "";
        //+1是未来把换行字符也取出来
        return ReadAsString(pos-ReadPosition()+1);
    }
    //获取一行数据，并且读偏移向后走
    std::string GetLineAndPop()
    {
        std::string str = GetLine();
        MoveReadOffset(str.size());
        return str;
    }
    //清空缓冲区
    void Clear()
    {
        _reader_idx = _writer_idx = 0;
    }
};


#define MAX_LISTEN 1024
class Socket
{
private:
    int _sockfd;
public:
    Socket():_sockfd(-1) {}
    Socket(int fd):_sockfd(fd) {}
    ~Socket(){Close();}
    int GetFd(){return _sockfd;}
    //创建套接字
    bool CreateSockfd()
    {
        _sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if(_sockfd<0)
        {
            ERR_LOG("CREATE SOCKET FAILED!!");
            return false;
        }
        return true;
    }
    //绑定地址信息
    bool Bind(const std::string &ip,uint16_t port)
    {
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr=inet_addr(ip.c_str());
        socklen_t len = sizeof(struct sockaddr_in);
        int ret = bind(_sockfd,(struct sockaddr*)&addr,len);
        if(ret<0)
        {
            ERR_LOG("BIND ADDRESS Failed!");
            return false;
        }
        return true;
    }
    //开始监听
    bool Listen(int backlog = MAX_LISTEN)
    {
        int ret = listen(_sockfd,backlog);
        if(ret<0)
        {
            ERR_LOG("SOCKET LISTEN FAILED!");
            return false;
        }
        return true;
    }
    //向服务器发起连接
    bool Connect(const std::string &ip,uint16_t port)
    {
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr=inet_addr(ip.c_str());
        socklen_t len = sizeof(struct sockaddr_in);
        int ret = connect(_sockfd,(struct sockaddr*)&addr,len);
        if(ret<0)
        {
            ERR_LOG("CONNECT ADDRESS Failed!");
            return false;
        }
        return true;
    }
    //获取新连接
    int Accept()
    {
        int newfd = accept(_sockfd,NULL,NULL);
        if(newfd < 0)
        {
            ERR_LOG("SOCKET ACCEPT FAILIED!");
            return -1;
        }
        return newfd;
    }
    //接收数据
    ssize_t Recv(void *buf,size_t len,int flag = 0)
    {
        ssize_t ret = recv(_sockfd,buf,len,flag);
        //DBG_LOG("%s",buf);
        if(ret<=0)
        {
            if(errno==EAGAIN||errno==EINTR)
            {
                return 0;
            }
            ERR_LOG("SOCKET RECV FAILED!!");
            return -1;
        }
        return ret;
    }
    //设置非阻塞
    ssize_t NonBlockRecv(void *buf,size_t len)
    {
        return Recv(buf,len,MSG_DONTWAIT);
    }
    //发送数据
    ssize_t Send(const void *buf,size_t len,int flag = 0)
    {
        ssize_t ret = send(_sockfd,buf,len,flag);
        if(ret<0)
        {
            if(errno==EAGAIN||errno==EINTR)
            {
                return 0;
            }
            ERR_LOG("SOCKET SEND FAILED!!");
            return -1;
        }
        return ret;
    }
    //非阻塞
    ssize_t NonBlockSend(void *buf,size_t len)
    {
        if(len==0) return 0;
        return Send(buf,len,MSG_DONTWAIT);
    }
    //关闭套接字
    void Close()
    {
        if(_sockfd!=-1)
        {
            close(_sockfd);
            _sockfd = -1;
        }
    }
    //创建一个服务端连接
    bool CreateServer(uint16_t port,const std::string& ip = "0.0.0.0",bool block_flag = false)
    {
        //创建套接字--绑定地址---进入监听状态--设置非阻塞---设置地址重用
        if(CreateSockfd()==false) return false;
        if(block_flag) NonBlock();
        if(Bind(ip,port)==false) return false;
        if(Listen()==false) return false;
        ReuseAddress();
        return true;
    }
    //创建一个客户端连接
    bool CreateClient(uint16_t port,const std::string& ip)
    {
        //创建套接字---申请连接
        if(CreateSockfd()==false) return false;
        if(Connect(ip,port)==false) return false;
        return true;
    }
    //设置套接字选项---开启地址端口重用
    void ReuseAddress()
    {
        int val = 1;
        //地址重用
        setsockopt(_sockfd,SOL_SOCKET,SO_REUSEADDR,(void*)&val,sizeof(int));
        //端口号重用
        val = 1;
        setsockopt(_sockfd,SOL_SOCKET,SO_REUSEPORT,(void*)&val,sizeof(int));
    }
    //设置套接字阻塞属性---设置为非阻塞
    void NonBlock()
    {
        int flag=fcntl(_sockfd,F_GETFL,0);
        fcntl(_sockfd,F_SETFL,flag|O_NONBLOCK);
    }
};

//对一个描述符的所有事件进行监控管理
//功能分两大类：第一大类是对于描述符的监控的操作。第二大类是事件触发后的处理的管理
//回调函数由Connection类进行设置，当启动可读或可写事件的监控，那么就会挂到EventLoop的epoll的红黑树上
class Poller;
class EventLoop;
class Channel
{
private:
    int _fd;
    EventLoop *_loop;
    uint32_t _events;//当前需要内核进行监控的事件，对标着epoll_ctl中的_events
    uint32_t _revents;//当前内核正在监控的就绪事件，里面的事件是就绪的了！
    using EventCallback = std::function<void()>;
    EventCallback _read_callback; //可读事件的回调函数
    EventCallback _write_callback;//可写事件的回调函数
    EventCallback _error_callback;//错误事件的回调函数
    EventCallback _close_callback;//连接断开事件的回调函数
    EventCallback _event_callback;//任意事件的回调函数
public:
    Channel(EventLoop *loop,int fd)
        :_fd(fd)
        ,_events(0)
        ,_revents(0)
        ,_loop(loop)
    {}
    int GetFd(){return _fd;}
    uint32_t GetEvents(){return _events;}//获取需要内核进行监控的事件
    void SetREvents(uint32_t revents) {_revents = revents;}//设置实际就绪事件
    void SetReadCallBack(const EventCallback &cb){_read_callback = cb;}//设置可读事件的回调函数
    void SetWriteCallBack(const EventCallback &cb){_write_callback = cb;}//设置可写事件的回调函数
    void SetErrorCallBack(const EventCallback &cb){_error_callback = cb;}//设置错误事件的回调函数
    void SetCloseCallBack(const EventCallback &cb){_close_callback = cb;}//设置连接断开的事件的回调函数
    void SetEventCallBack(const EventCallback &cb){_event_callback = cb;}//设置任意事件的回调函数
    //是否监控了可读事件
    bool ReadAble()
    {
        return (_events & EPOLLIN);
    }
    //是否监控了可写事件
    bool WriteAble()
    {
        return (_events & EPOLLOUT);
    }
    //监控可读事件
    void EnableRead()
    {
        _events|=EPOLLIN;
        //挂到红黑树上进行监控
        Update();
    }
    //监控可写事件
    void EnableWrite()
    {
        _events|=EPOLLOUT;
        //挂到红黑树上进行监控
        Update();
    }
    //取消可读事件的监控
    void DisableWrite()
    {
        _events&=~EPOLLOUT;
        //从红黑树上摘下来
        Update();
    }
    //取消可写事件的监控
    void DisableRead()
    {
        _events&=~EPOLLIN;
        //从红黑树上摘下来
        Update();
    }
    //取消所有事件的监控
    void DisableAll()
    {
        _events = 0;
        Update();
    }
    //移除监控，移除就是将描述从epoll的红黑树上移除，不再监控描述符的事件
    void Remove();
    void Update();
    //事件处理，一旦触发了事件，就会调用这个函数，然后调用相应的回调函数
    void HandleEvent()
    {
        if((_revents&EPOLLIN) || (_revents&EPOLLRDHUP) ||(_revents&EPOLLPRI))
        {
            //调用一次任意事件回调函数
            if(_event_callback) _event_callback();
            if(_read_callback) _read_callback();
        }

        /*有可能会释放连接的操作事件，⼀次只处理⼀个*/
        if(_revents & EPOLLOUT)
        {
            if(_event_callback) _event_callback();//放到事件处理完后调用，比如刷新活跃度
            if(_write_callback) _write_callback();
            //调用一次任意事件回调函数
        }
        else if((_revents & EPOLLERR))
        {
            if(_event_callback) _event_callback();
            if(_error_callback) _error_callback();//一旦出错，就会释放连接，没必要调用任意事件回调函数，而可以放到前面调用
        }
        else if((_revents & EPOLLHUP))
        {
            if(_event_callback) _event_callback();
            if(_close_callback) _close_callback();
        }
    }
};


//对epoll的常用操作进行封装
#define MAX_EPOLLEVENTS 1024
class Poller
{
private:
    int _epfd;
    struct epoll_event _evs[MAX_EPOLLEVENTS];
    std::unordered_map<int,Channel*> _channels;
private:
        //对epoll直接操作
        void Update(Channel *channel, int op) 
        {
            // int epoll_ctl(int epfd, int op, int fd, struct epoll_event*ev);
            int fd = channel->GetFd();
            struct epoll_event ev;
            ev.data.fd = fd;
            ev.events = channel->GetEvents();
            int ret = epoll_ctl(_epfd, op, fd, &ev);
            if (ret < 0) 
            {
                ERR_LOG("EPOLLCTL FAILED!");
            }
            return;
        }
        //判断一个channel是否已经添加到事件监控
        bool HasChannel(Channel *channel) 
        {
            auto it = _channels.find(channel->GetFd());
            if (it == _channels.end()) 
            {
                return false;
            }
            return true;
        }
public:
    Poller()
    {
        _epfd = epoll_create(MAX_EPOLLEVENTS);
        if(_epfd < 0)
        {
            ERR_LOG("EPOLL CREATE FAILED!");
            abort();
        }
    }
    //添加或修改事件监控
    void UpdateEvent(Channel *channel)
    {
        //先查看channel是否已经添加了事件监控，如果没有，则添加，如果有，则修改
        bool ret = HasChannel(channel);
        if(ret==false)
        {
            _channels.insert(std::make_pair(channel->GetFd(),channel));//建立映射关系，方便后续操作
            return Update(channel,EPOLL_CTL_ADD);
        }
        return Update(channel,EPOLL_CTL_MOD);
    }
    //移除事件监控
    void RemoveEvent(Channel *channel)
    {
        //首先看看这个channel在不在映射关系中，在的话移除，随后移除监控
        auto it = _channels.find(channel->GetFd());
        if(it!=_channels.end())
        {
            _channels.erase(it);
        }
        Update(channel,EPOLL_CTL_DEL);
    }
    //返回活跃连接
    void Poll(std::vector<Channel*> *active)
    {
        //使用epoll_wait将就绪的事件存放在_evs中，将_evs中的就绪事件集合设置到channel中，将channel存放到active返回给用户
        int nfds = epoll_wait(_epfd,_evs,MAX_EPOLLEVENTS,-1);
        if(nfds < 0)
        {
            if(errno==EINTR) return;
            ERR_LOG("EPOLL WAIT FAILD");
            abort();
        }
        for(int i = 0;i<nfds;++i)
        {
            auto it = _channels.find(_evs[i].data.fd);
            assert(it!=_channels.end());
            it->second->SetREvents(_evs[i].events);
            active->push_back(it->second);
        }
        return;
    }
};

//定时器任务类---即每一个定时器的任务
using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
class TimerTask
{
private:
    uint64_t _id;//每一个任务都需要有id来标识它，以便后续的操作
    uint64_t _timeout;//定时任务的超时时间---这个时间一旦超时，那么这个任务就会被执行
    TaskFunc _task_cb;//定时器对象要执行的定时任务
    ReleaseFunc _release;//用于删除TimerWheel中保存的定时器对象信息
    bool _canceled;//false--表示没有被取消，true表示被取消
public:
    TimerTask(uint64_t id,uint64_t delay,const TaskFunc &cb)
        :_id(id)
        ,_timeout(delay)
        ,_task_cb(cb)
        ,_canceled(false)
    {}
    //定时器对象销毁时，即时间超时，执行任务
    ~TimerTask()
    {
        if(_canceled==false) _task_cb();//这个任务没有被取消，才能去执行，被取消了执行不了
        _release();
    }

    void Cancel(){_canceled = true;}

    //设置删除定时器对象信息的函数
    void SetRelease(const ReleaseFunc &cb){_release = cb;}
    uint64_t GetDelayTime(){return _timeout;}
};
//时间轮
class TimerWheel
{
private:
    using PtrTask = std::shared_ptr<TimerTask>;
    using WeakTask = std::weak_ptr<TimerTask>;
    int _tick;//走到哪，执行到哪个任务
    int _capacity;//时间轮最大数量，就是最大延迟时间
    std::vector<std::vector<PtrTask>> _wheel;//时间轮---二维数组--？？？---存放的是使用智能指针管理起来的定时任务
    std::unordered_map<uint64_t,WeakTask> _timers;//用于通过id找到定时器任务，使用weak_ptr来管理定时器任务对象，与shared_ptr共享计数
    EventLoop *_loop;
    int _timerfd;//定时器描述符,通过eventloop进行事件监控和事件处理
    std::unique_ptr<Channel> _timer_channel;

private:
    void RemoveTimer(uint64_t id)
    {
        auto it = _timers.find(id);
        if(it!=_timers.end())
        {
            _timers.erase(it);
        }
    }

    static int CreatTimerFd()
    {
        int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
        if(timerfd < 0)
        {
            ERR_LOG("TIMERFD CREATE FILED!");
            abort();
        }

        struct itimerspec itime;
        itime.it_value.tv_sec = 1;
        itime.it_value.tv_nsec=0;//第一次超时时间为1s后
        itime.it_interval.tv_sec = 1;
        itime.it_interval.tv_nsec = 0;//第一次超时后，往后每次的超时时间为1s后
        timerfd_settime(timerfd,0,&itime,NULL);
        return timerfd;
    }

    void ReadTimerFd()
    {
        uint64_t times;
        int ret = read(_timerfd,&times,8);
        if(ret < 0)
        {
            ERR_LOG("READ TIMERFD FAILED!");
            abort();
        }
        return;
    }

    //指针往后走啦---每秒钟执行一次这个函数，相当于秒针往后走一步，走到的位置的任务进行执行
    void RunTimerTask()
    {
        _tick = (_tick+1)%_capacity;
        _wheel[_tick].clear();//清空指针指定的位置，这样就会把数组中保存的所有管理定时器对象的shared_ptr释放掉
    }

    //时间到了，读取timerfd，执行定时器任务
    void OnTime()
    {
        ReadTimerFd();
        RunTimerTask();
    }

    //添加定时任务,添加到_timers映射起来---需要的是定时任务的id、延迟时间和执行的任务
    void TimerAddInLoop(uint64_t id,uint64_t delay,const TaskFunc &cb)
    {
        //步骤：1.new一个定时任务，使用shared_ptr进行管理  2.设置删除方法  3.使用哈希映射起来 4.添加到时间轮中
        PtrTask pt(new TimerTask(id,delay,cb));
        pt->SetRelease(std::bind(&TimerWheel::RemoveTimer,this,id));
        //在使用哈希映射时，不能使用shared_ptr，因为这样会永久保存着一个shared_ptr的对象，计数不会变为0
        //而是使用weak_ptr，与时间轮的任务（对应起来的那个）共享计数，当任务执行，计数减1，那么在哈希中的weak_ptr
        //的计数也跟着减1，从而删除.
        _timers[id] = WeakTask(pt);
        int pos = (_tick+delay)%_capacity;
        _wheel[pos].push_back(pt);
    }

    //延迟/刷新定时任务----需要的是需要刷新或延迟的任务的id
    void TimerRefreshInLoop(uint64_t id)
    {
        //通过保存的定时器对象的weak_ptr构造一个shared_ptr出来，添加到时间轮中
        auto it = _timers.find(id);
        if(it==_timers.end())
        {
            return;//没找到定时任务，无法刷新
        }
        //找到后，构造
        PtrTask pt=it->second.lock();
        int delay = pt->GetDelayTime();
        int pos = (_tick+delay)%_capacity;
        _wheel[pos].push_back(pt);
    }

    //取消定时任务
    void TimerCancelInLoop(uint64_t id)
    {
        auto it = _timers.find(id);
        if(it==_timers.end())
        {
            return;//没找到定时任务，无法刷新
        }
        PtrTask pt=it->second.lock();
        if(pt) pt->Cancel();
    }
public:
    TimerWheel(EventLoop *loop)
        :_tick(0)
        ,_capacity(60)
        ,_wheel(_capacity)
        ,_loop(loop)
        ,_timerfd(CreatTimerFd())
        ,_timer_channel(new Channel(_loop,_timerfd))
    {
        _timer_channel->SetReadCallBack(std::bind(&TimerWheel::OnTime,this));
        _timer_channel->EnableRead();//每1秒钟都会触发读时间
    }

    void TimerAdd(uint64_t id,uint64_t delay,const TaskFunc &cb);
    void TimerRefresh(uint64_t id);
    void TimerCancel(uint64_t id);

    /*存在线程安全，只能在模块内自己调用*/
    bool HasTimer(uint64_t id)
    {
        auto it = _timers.find(id);
        if(it==_timers.end())
        {
            return false;//没找到定时任务
        }
        return true;
    }
};
//EventLoop
class EventLoop
{
private:
    using Functor = std::function<void()>;
    std::thread::id _thread_id;//线程ID
    int _event_fd;//eventfd唤醒IO事件监控有可能导致的阻塞
    Poller _poller;//进行所有描述符的事件监控
    std::unique_ptr<Channel> _event_channel;
    std::vector<Functor> _task;//任务池
    std::mutex _mutex;//实现任务池操作的线程安全
    TimerWheel _time_wheel;
public:
    //执行任务池中所有任务
    void RunAllTask()
    {
        //将任务池中的任务拿出来，然后一一执行
        std::vector<Functor> functor;
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _task.swap(functor);
        }
        //执行
        for(auto&f : functor)
        {
            f();
        }
        return;
    }
    //创建eventfd
    static int CreateEventFd()
    {
        int efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
        if (efd < 0) 
        {
            ERR_LOG("CREATE EVENTFD FAILED!!");
            abort();//让程序异常退出
        }
        return efd;
    }
    //读取eventfd的值，也就是通知次数，情况通知次数可以继续进行时间通知
    void ReadEventFd()
    {
        uint64_t res = 0;
        int ret = read(_event_fd,&res,sizeof(res));//将_event_fd中的通知次数读取出来，清空一下
        if (ret < 0) {
            //EINTR -- 被信号打断；   EAGAIN -- 表示无数据可读
            if (errno == EINTR || errno == EAGAIN) {
                return;
            }
            ERR_LOG("READ EVENTFD FAILED!");
            abort();
        }
        return;
    }
    //唤醒eventfd，也就是往eventfd写入值
    void WeakUpEventFd()
    {
        uint64_t val = 1;
        int ret = write(_event_fd,&val,sizeof(val));//往_event_fd中写入一个数据，代表需要通知
        if (ret < 0) 
        {
            //EINTR -- 被信号打断；   EAGAIN -- 对方接收缓冲区满了
            if (errno == EINTR || errno == EAGAIN) 
            {
                return;
            }
            ERR_LOG("Write EVENTFD FAILED!");
            abort();
        }
        return ;
    }
public:
    EventLoop()
        :_thread_id(std::this_thread::get_id())
        ,_event_fd(CreateEventFd())
        ,_event_channel(new Channel(this,_event_fd))
        ,_time_wheel(this)
    {
        //给eventfd添加可读事件回调函数，用于读取通知次数
        _event_channel->SetReadCallBack(std::bind(&EventLoop::ReadEventFd,this));
        //启动eventfd的可读事件监控
        _event_channel->EnableRead();
    }
    //启动eventloop
    //三步走---事件监控---》事件处理---》执行任务
    void Start()
    {
        while(1)
        {
            //事件监控
            std::vector<Channel*> actives;
            _poller.Poll(&actives);
            //事件处理
            for(auto& channel:actives)
            {
                channel->HandleEvent();
            }
            //实现任务
            RunAllTask();
        }

    }
    //判断当前线程是否是eventloop对应的线程
    bool IsInLoop()
    {
        return (_thread_id==std::this_thread::get_id());
    }
    //断言
    void AssertInLoop()
    {
        assert(_thread_id==std::this_thread::get_id());
    }
    //判断将要执行的任务是否处于对应的线程
    void RunInLoop(const Functor &cb)
    {
        if(IsInLoop())
        {
            return cb();
        }
        QueueInLoop(cb);
    }
    //将操作压入任务池
    void QueueInLoop(const Functor &cb)
    {
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _task.push_back(cb);
        }
        //添加任务到任务池后，需要唤醒一次epoll
        //因为有可能没有事件就绪，导致epoll阻塞
        //给eventfd写入一个数据，eventfd就会触发可读事件
        WeakUpEventFd();
    }
    //添加/修改描述符的事件监控
    void UpdateEvent(Channel* channel)
    {
        return _poller.UpdateEvent(channel);
    }
    //移除描述符的事件监控
    void RemoveEvent(Channel* channel)
    {
        return _poller.RemoveEvent(channel);
    }

    void TimerAdd(uint64_t id,uint64_t delay,const TaskFunc &cb)
    {
        return _time_wheel.TimerAdd(id,delay,cb);
    }

    void TimerRefresh(uint64_t id)
    {
        return _time_wheel.TimerRefresh(id);
    }

    void TimerCancel(uint64_t id)
    {
        return _time_wheel.TimerCancel(id);
    }

    bool HasTimer(uint64_t id)
    {
        return _time_wheel.HasTimer(id);
    }
};


typedef enum {
    DISCONNECTED, //连接断开状态
    CONNECTING,   //连接建立成功状态--刚建立状态
    CONNECTED,    //连接已经建立成功，可以进行连接处理--可通信状态
    DISCONNECTING //连接待断开状态
} ConStatu;
class Connection;
using PtrConnection = std::shared_ptr<Connection>;
class Connection : public std::enable_shared_from_this<Connection>
{
private:
    uint64_t _conn_id; //连接的唯一ID，便于连接的管理和查找等操作
    //uint64_t _timer_id;//定时器id，必须是唯一的，为了简化操作，使用_conn_id作为定时器id
    int _sockfd;       //连接关联的文件描述符
    bool _enable_inactive_release;//连接是否启动了非活跃销毁的判断标志，默认为false，表示不启动。true表示启动
    EventLoop *_loop;  //连接所关联的eventloop，一个连接一共eventloop，保证线程安全
    ConStatu _statu;   //连接的状态
    Socket _socket;    //套接字操作管理
    Channel _channel;  //连接的事件管理
    Buffer _in_buffer; //输入缓冲区---存放从socket中读取到的数据
    Buffer _out_buffer;//输出缓冲区--存放发送给对端的数据
    Any _context;      //请求的接收处理上下文--记录数据处理的位置，以便下一次处理时，从上一次位置往下处理，但是协议的格式不一样，需要通用类型来处理

    using ConnectedCallBack = std::function<void(const PtrConnection&)>;//连接创建后需要做的事件的处理回调
    using MessageCallBack = std::function<void(const PtrConnection&,Buffer *)>;//业务处理回调
    using CloseCallBack = std::function<void(const PtrConnection&)>;//关闭连接处理回调
    using EventCallBack = std::function<void(const PtrConnection&)>;//任意事件处理回调
    ConnectedCallBack _connected_callback;
    MessageCallBack _message_callback;
    CloseCallBack _close_callback;
    EventCallBack _event_callback;
    CloseCallBack _server_close_callback;
private:
    /*五个channel事件的回调函数*/
    //描述符可读事件触发后的函数，接收socket数据放到接收缓冲区中，然后调用_message_callback
    void HandleRead()
    {
        //1.接收socket数据放到临时缓冲区中
        char buf[65536]={0};
        ssize_t ret = _socket.NonBlockRecv(buf,65535);//非阻塞读取
        if(ret < 0){
            //出错了
            return ShutDownInLoop();//出错了不能直接关闭连接，需要看一下发送缓冲区是否有数据待发送
        }
        else if(ret == 0) {
            //没有读取到数据
            return;
        }
        //放入接收缓冲区
        _in_buffer.WriteAndPush(buf,ret);
        //2.调用_message_callback
        if(_in_buffer.ReadAbleSize()>0)
        {
            //shared_from_this()从当前对象自身获取自身的shared_ptr管理的对象，需要继承模板类：enable_shared_from_this
            return _message_callback(shared_from_this(),&_in_buffer);
        }
    }
    //描述符可写事件触发后调用的函数，将发送缓冲区中的数据进行发送
    void HandleWrite()
    {
        //_out_buffer保存的是要发送的数据
        ssize_t ret = _socket.NonBlockSend(_out_buffer.ReadPosition(),_out_buffer.ReadAbleSize());
        if(ret < 0)
        {
            //发送错误，直接关闭连接
            //判断写入（接收）缓冲区中是否还有数据，如果有，就处理数据先
            if(_in_buffer.ReadAbleSize() > 0)
            {
                _message_callback(shared_from_this(),&_in_buffer);
            }
            //数据处理完，关闭连接
            return Release();
        }
        //发送成功，需要把读偏移量往后走
        _out_buffer.MoveReadOffset(ret);
        //读偏移量往后走，判断一下是否还有可读（可发送）的数据，如果没有，就关闭写事件，判断一下连接是否处于待关闭状态，如果是，那么直接关闭连接
        if(_out_buffer.ReadAbleSize()==0)
        {
            _channel.DisableWrite();
            if(_statu==DISCONNECTING)
            {
                return Release();
            }
        }
        return;
    }
    //描述符触发挂断事件
    void HandleClose()
    {
        //一旦关闭了连接，套接字啥也干不了了，自然也不能进行发送数据来通信
        //此时看看自己的接收缓冲区有没有数据要处理的，有就处理一下吧
        if(_in_buffer.ReadAbleSize()>0)
        {
            _message_callback(shared_from_this(),&_in_buffer);
        }
        return ReleaseInLoop();

    }
    //描述符触发错误事件
    void HandleError()
    {
        /*出错了，那有数据就处理一下，没就挂断吧*/
        return HandleClose();
    }
    //描述符触发任意事件
    void HandleEvent()
    {
        /*触发任意事件，常见操作就是：1.刷新连接活跃度，延迟定时销毁任务 2.调用组件使用者的任意事件回调函数*/
        if(_enable_inactive_release==true)
        {
            _loop->TimerRefresh(_conn_id);
        }
        if(_event_callback)
        {
            _event_callback(shared_from_this());
        }
    }
    //连接获取之后，所处的状态下需要进行各种设置（给channel设置时间回调，启动读监控）
    void EstablishInLoop()
    {
        //当前的状态一定是半连接状态，也就是连接刚建立，但是各种回调函数都还没设置的时候
        //1.修改连接状态为成功建立连接状态  2.启动读事件监控 3.调用回调函数
        assert(_statu==CONNECTING);
        _statu = CONNECTED;
        _channel.EnableRead();
        if(_connected_callback) _connected_callback(shared_from_this());
    }
    //实际释放连接的接口
    void ReleaseInLoop()
    {
        //1.修改连接状态为已断开连接状态 
        _statu = DISCONNECTED;
        // 2.移除事件监控
        _channel.Remove();
        // 3.关闭描述符
        _socket.Close();
        //4.如果当前定时器队列中还有定时销毁任务，则取消任务
        if(_loop->HasTimer(_conn_id)) CancelInactiveReleaseInLoop();
        //5.调用关闭回调函数
        if(_close_callback) _close_callback(shared_from_this());
        //移除服务器内部管理的连接信息
        if(_server_close_callback) _server_close_callback(shared_from_this());
    }

    //这个接口并不是实际是发送接口，而是把数据发送到了发送缓冲区中，然后启动写事件监控
    void SendInLoop(Buffer buf)
    {
        if(_statu==DISCONNECTED) return;
        //1.把数据发送到发送缓冲区
        _out_buffer.WriteBufferAndPush(buf);
        //2.启动可写事件监控
        //判断一下是否添加了写事件的监控
        if(_channel.WriteAble()==false)
        {
            _channel.EnableWrite();
        }
    }

    //这个关闭操作不是实际的连接释放操作，需要判断还有没有数据要处理，待发送
    void ShutDownInLoop()
    {
        //思路是先将连接状态改成半关闭状态，然后需要判断接收缓冲区和发送缓冲区是否还有数据要处理
        /*1.改变状态*/
        _statu = DISCONNECTING;
        /*2.判断接收缓冲区是否还有数据要处理，有就处理*/
        if(_in_buffer.ReadAbleSize()>0)
        {
            if(_message_callback) _message_callback(shared_from_this(),&_in_buffer);
        }
        /*3.判断发送缓冲区是否有数据需要处理*/
        /*要么有数据需要处理，启动写事件监控，触发后调用HandleWrite，发送完关闭连接。要么没数据，直接关闭*/
        if(_out_buffer.ReadAbleSize() > 0)
        {
            //判断一下是否开启了写事件监控
            if(_channel.WriteAble()==false)
            {
                _channel.EnableWrite();
            }
        }
        if(_out_buffer.ReadAbleSize()==0)
        {
            ReleaseInLoop();
        }
    }

    //启动非活跃连接超时释放规则
    void EnableInactiveReleaseInLoop(int sec)
    {
        DBG_LOG("EnableInactiveReleaseInLoop");
        //1.将判断标志_enable_inactive_release改成true，表示启动非活跃释放
        _enable_inactive_release= true;
        //2.如果当前定时销毁任务已经存在，则刷新延迟
        if(_loop->HasTimer(_conn_id))
        {
            _loop->TimerRefresh(_conn_id);
        }
        //3.如果定时销毁任务不存在，则添加
        _loop->TimerAdd(_conn_id,sec,std::bind(&Connection::ReleaseInLoop,this));
    }

    //取消非活跃连接超时规则
    void CancelInactiveReleaseInLoop()
    {
        //1.将判断标志_enable_inactive_release置为false
        _enable_inactive_release= false;
        //2.移除定时销毁任务
        if(_loop->HasTimer(_conn_id))
        {
            _loop->TimerCancel(_conn_id);
        }
    }

    //升级协议--协议升级，需要重新设置回调函数和上下文
    void UpgradeInLoop(const Any &context,
                    const ConnectedCallBack &conn,
                    const MessageCallBack &msg,
                    const CloseCallBack &closed,
                    const EventCallBack &event)
    {
        //1.设置上下文
        _context = context;
        //2.设置回调函数
        _connected_callback = conn;
        _message_callback = msg;
        _close_callback = closed;
        _event_callback = event;
    }
public:
    Connection(EventLoop *loop,uint64_t conn_id,int sockfd)
        :_conn_id(conn_id)
        ,_sockfd(sockfd)
        ,_enable_inactive_release(false)
        ,_loop(loop)
        ,_statu(CONNECTING)
        ,_socket(_sockfd)
        ,_channel(loop,_sockfd)
    {
        //设置回调函数
        _channel.SetCloseCallBack(std::bind(&Connection::HandleClose,this));
        _channel.SetEventCallBack(std::bind(&Connection::HandleEvent,this));
        _channel.SetReadCallBack(std::bind(&Connection::HandleRead,this));
        _channel.SetWriteCallBack(std::bind(&Connection::HandleWrite,this));
        _channel.SetErrorCallBack(std::bind(&Connection::HandleError,this));
    }
    ~Connection(){DBG_LOG("RELEASE CONNECTION:%p",this);}
    //获取描述符
    int GetFd(){return _sockfd;}
    //获取连接id
    int GetConnId(){return _conn_id;}
    //是否处于CONNECTED状态
    bool Connected(){return _statu==CONNECTED;}
    //设置上下文--连接建立完成时进行设置调用
    void SetContext(const Any &context){_context = context;}
    //获取上下文--返回的是指针，保证是同一个上下文
    Any *GetContext(){return &_context;}
    void SetConnectedCallBack(const ConnectedCallBack &cb){_connected_callback = cb;}
    void SetMessageCallBack(const MessageCallBack &cb){_message_callback = cb;}
    void SetCloseCallBack(const CloseCallBack &cb){_close_callback = cb;}
    void SetEventCallBack(const EventCallBack &cb){_event_callback = cb;}
    void SetSrvCloseCallBack(const CloseCallBack &cb){_server_close_callback = cb;}
    //连接建立就绪后，进行channel回调设置，启动读监控，调用_connected_callback进行设置
    void Establish(){ _loop->RunInLoop(std::bind(&Connection::EstablishInLoop,this));}
    //发送数据，将数据发送到发送缓冲区，启动写事件监控
    void Send(const char *data,size_t len)
    {
        //外界传入的data可能是一个临时的空间，我们现在只是把发送操作压入了任务池，有可能在执行的
        //时候，这个data指向的空间已经被释放了,因此可以重新构建一个对象出来
        Buffer buf;
        buf.WriteAndPush(data,len);
        _loop->RunInLoop(std::bind(&Connection::SendInLoop,this,buf));
    }
    void Release(){_loop->RunInLoop(std::bind(&Connection::ReleaseInLoop,this));}
    //提供组件使用者的关闭连接--不能直接关闭，因为可能还有数据没有发送完毕，因此设置为待关闭状态，启动写事件监控
    void ShutDown(){_loop->RunInLoop(std::bind(&Connection::ShutDownInLoop,this));}
    //启动非活跃销毁，定义多长时间无通信就是非活跃，添加定时任务
    void EnableInactiveRelease(int sec)
    {
        DBG_LOG("EnableInactiveRelease");
        _loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop,this,sec));
    }
    //取消非活跃销毁
    void CancelInactiveRelease()
    {
        _loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop,this));
    }
    //协议升级/切换协议---重置上下文以及阶段性处理函数--必须马上执行，并且需要在本线程内执行
    //因为如果压入到任务队列，然而后面来了一个任务，需要是升级后的协议才能完成的任务，但此时协议并没有升级
    //使用原协议去处理就会出问题，因此，需要马上执行，先判断是否在本线程内
    void Upgrade(const Any &context,const ConnectedCallBack &conn,const MessageCallBack &msg,
                const CloseCallBack &closed,const EventCallBack &event)
    {
        _loop->AssertInLoop();
        _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop,this,context,conn,msg,closed,event));
    } 
};

class Acceptor
{
private:
    Socket _socket;//用于创建监听套接字
    EventLoop *_loop;//用于对监听套接字进行事件监控
    Channel _channel; //用于对监听套接字进行事件管理

    using AcceptCallBack = std::function<void(int)>;
    AcceptCallBack _accept_callback;
private:
    //监听套接字的读事件回调处理函数---获取新连接，调用_accept_callback函数进行新连接的处理
    void HandleRead()
    {
        //获取新连接
        int newfd = _socket.Accept();
        if(newfd < 0) return;

        if(_accept_callback) _accept_callback(newfd);
    }
    int CreateServer(int port)
    {
        int ret = _socket.CreateServer(port);
        assert(ret==true);
        return _socket.GetFd();
    }
public:
    /*不能将启动读事件监控，放到构造函数中，必须在设置回调函数后，再去启动
      否则有可能造成启动监控后，立即有事件，处理的时候，回调函数还没设置：新连接得不到处理，切造成资源泄漏*/
    Acceptor(EventLoop *loop,int port)
        :_loop(loop)
        ,_socket(CreateServer(port))
        ,_channel(loop,_socket.GetFd())
    {
        _channel.SetReadCallBack(std::bind(&Acceptor::HandleRead,this));
        
    }
    void SetAcceptCallBack(const AcceptCallBack &cb){_accept_callback = cb;}

    void Listen() {_channel.EnableRead();}
};

class LoopThread
{
private:
    /*互斥锁和条件变量用于实现_loop获取的同步关系*/
    std::mutex _mutex;  //互斥锁
    std::condition_variable _cond;//条件变量
    EventLoop *_loop;   //EventLoop指针变量，这个对象需要在线程内部实例化，否则会跟主线程id绑定在一起
    std::thread _thread;//EventLoop对应的线程
private:
    /*实例化EventLoop对象，并且开始运行EventLoop模块的功能*/
    void ThreadEntry()
    {
        EventLoop loop;//不通过new，是因为想要通过LoopThread来管理生命周期
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _loop = &loop;
            _cond.notify_all();//唤醒有可能被阻塞的线程
        }
        loop.Start();
    }
public:
    /*创建线程、设定线程入口函数*/
    LoopThread()
        :_loop(NULL)
        ,_thread(std::bind(&LoopThread::ThreadEntry,this))
    {}
    /*返回当前线程关联的Eventloop对象指针，因为要给每一个新连接一个Eventloop*/
    EventLoop *GetLoop()
    {
        EventLoop *loop = NULL;
        {
            std::unique_lock<std::mutex> lock(_mutex);//加锁
            _cond.wait(lock,[&](){return _loop!=NULL;});//如果_loop为空，则一直等待，待_loop创建出来后，唤醒
            loop = _loop;
        }
        return loop;
    }
};

class LoopThreadPool
{
private:
    int _thread_count;//从属线程的数量
    int _next_loop_id;//Eventloop池的索引
    EventLoop *_base_loop;//运行在主线程、从属线程数量为0，则所有操作都在baseloop中进行
    std::vector<LoopThread*> _threads;//保存所有LoopThread对象
    std::vector<EventLoop*> _loops;//从属线程数量大于0，则从_loops中进行线程EventLoop分配
public:
    LoopThreadPool(EventLoop *baseloop)
        :_thread_count(0)
        ,_next_loop_id(0)
        ,_base_loop(baseloop)
    {}
    //设置线程数量
    void SetThreadCount(int count){ _thread_count = count; }
    /*创建所有从属线程*/
    void Create()
    {
        if(_thread_count > 0)
        {
            _threads.resize(_thread_count);
            _loops.resize(_thread_count);
            for(int i = 0;i<_thread_count;++i)
            {
                _threads[i] = new LoopThread();
                _loops[i] = _threads[i]->GetLoop();
            }
        }
        return;
    }
    
    /*分配EventLoop*/
    EventLoop *NextLoop()
    {
        if(_thread_count==0) return _base_loop;
        _next_loop_id = (_next_loop_id + 1) % _thread_count;
        return _loops[_next_loop_id];
    }
};

class TCPServer
{
private:
    uint64_t _next_id; //这是一个自动增长的连接ID
    int _port;         //端口号
    int _timeout;      //非活跃连接的时长统计---超过这个时间就是非活跃连接
    bool _enable_inactive_release;//是否启动了非活跃连接超时销毁的标志
    EventLoop _base_loop;//主线程的EventLoop对象，负责监听事件的处理
    Acceptor _acceptor;//这是监听套接字的管理对象
    LoopThreadPool _pool;//这是从属EventLoop线程池
    std::unordered_map<uint64_t,PtrConnection> _conns;//保存管理所有连接的对象
    
    using ConnectedCallBack = std::function<void(const PtrConnection&)>;//连接创建后需要做的事件的处理回调
    using MessageCallBack = std::function<void(const PtrConnection&,Buffer *)>;//业务处理回调
    using CloseCallBack = std::function<void(const PtrConnection&)>;//关闭连接处理回调
    using EventCallBack = std::function<void(const PtrConnection&)>;//任意事件处理回调
    using Functor = std::function<void()>;
    ConnectedCallBack _connected_callback;
    MessageCallBack _message_callback;
    CloseCallBack _close_callback;
    EventCallBack _event_callback;

private:
    void RunAfterInLoop(const Functor &task,int delay)
    {
        _next_id++;
        _base_loop.TimerAdd(_next_id,delay,task);
    }

    //为新连接构造一个Connection进行管理
    void NewConnection(int fd) {
        DBG_LOG("创建新连接");
        _next_id++;
        PtrConnection conn(new Connection(_pool.NextLoop(), _next_id, fd));
        conn->SetMessageCallBack(_message_callback);
        conn->SetCloseCallBack(_close_callback);
        conn->SetConnectedCallBack(_connected_callback);
        conn->SetEventCallBack(_event_callback);
        conn->SetSrvCloseCallBack(std::bind(&TCPServer::RemoveConnection, this, std::placeholders::_1));
        if (_enable_inactive_release) conn->EnableInactiveRelease(_timeout);//启动非活跃超时销毁
        conn->Establish();//就绪初始化
        _conns.insert(std::make_pair(_next_id, conn));
    }

    void RemoveConnectionInLoop(const PtrConnection &conn)
    {
        int id = conn->GetConnId();
        auto it = _conns.find(id);
        if(it!=_conns.end())
        {
            _conns.erase(it);
        }
    }

    void RemoveConnection(const PtrConnection &conn)
    {
        _base_loop.RunInLoop(std::bind(&TCPServer::RemoveConnectionInLoop,this,conn));
    }

public:
    TCPServer(int port)
        :_port(port)
        ,_next_id(0)
        ,_timeout(0)
        ,_enable_inactive_release(false)
        ,_acceptor(&_base_loop,port)
        ,_pool(&_base_loop)
    {
        _acceptor.SetAcceptCallBack(std::bind(&TCPServer::NewConnection, this, std::placeholders::_1));
        _acceptor.Listen();//将监听套接字挂到baseloop上
    }
    /*设置回调函数*/
    void SetThreadCount(int count) {return _pool.SetThreadCount(count);}
    void SetConnectedCallBack(const ConnectedCallBack &cb){_connected_callback = cb;}
    void SetMessageCallBack(const MessageCallBack &cb){_message_callback = cb;}
    void SetCloseCallBack(const CloseCallBack &cb){_close_callback = cb;}
    void SetEventCallBack(const EventCallBack &cb){_event_callback = cb;}
    /*启动非活跃超时连接销毁*/
    void EnableInactiveRelease(int timeout) {_timeout = timeout;_enable_inactive_release = true;}
    //用于添加一个定时任务
    void RunAfter(const Functor &task,int delay)
    {
        _base_loop.RunInLoop(std::bind(&TCPServer::RunAfterInLoop,this,task,delay));
    }

    void Start(){_pool.Create();_base_loop.Start();}

};


void Channel::Remove(){return _loop->RemoveEvent(this);}
void Channel::Update(){return _loop->UpdateEvent(this);}
void TimerWheel::TimerAdd(uint64_t id,uint64_t delay,const TaskFunc &cb)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerAddInLoop,this,id,delay,cb));
}
void TimerWheel::TimerRefresh(uint64_t id)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerRefreshInLoop,this,id));
}

void TimerWheel::TimerCancel(uint64_t id)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerCancelInLoop,this,id));
}

class NetWok
{
public:
    NetWok()
    {
        DBG_LOG("SIGPIE INIT");
        signal(SIGPIPE,SIG_IGN);
    }
};
static NetWok nw;

#endif